﻿using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using GitSharp;

namespace GitCapture
{
    public partial class MainForm : Form
    {
        private GitReader _gitReader;
        private IniVisitor _iniVisitor;

        public MainForm()
        {
            InitializeComponent();
        }

        #region Event

        private void MainForm_Load(object sender, EventArgs e)
        {
            var iniFile = Application.StartupPath + "\\config.ini";
            _iniVisitor = new IniVisitor(iniFile);
            txtGitUrl.Text = _iniVisitor.GetValue("info", "GitUrl");
            txtExportDir.Text = _iniVisitor.GetValue("info", "ExportDir");

            _gitReader = new GitReader();
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_gitReader != null && _gitReader.IsLoad)
            {
                _gitReader.Close();
            }

            _iniVisitor.SetValue("info", "GitUrl", txtGitUrl.Text.Trim());
            _iniVisitor.SetValue("info", "ExportDir", txtExportDir.Text.Trim());
        }

        private void lvwCommitList_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            var commitName = e.Item.Tag.ToString();
            LoadCommit(commitName);
        }

        private async void btnLoad_Click(object sender, EventArgs e)
        {
            var gitUrl = txtGitUrl.Text.Trim();
            if (string.IsNullOrWhiteSpace(gitUrl))
                return;
            try
            {

                _gitReader.Load(gitUrl);

                lvwCommitList.Items.Clear();
                var commitList = await Task.Run(() => _gitReader.GetCommitList());
                foreach (var commit in commitList)
                {
                    var newItem = new ListViewItem(new[]
                    {
                        commit.AuthorDate.ToString("yyyy-MM-dd HH:mm:ss"),
                        commit.Author.Name,
                        commit.Message
                    }) { Tag = commit.Hash };
                    lvwCommitList.Items.Add(newItem);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btnExport_Click(object sender, EventArgs e)
        {
            if (lvwCommitList.SelectedItems.Count == 0)
                return;
            if (string.IsNullOrWhiteSpace(txtExportDir.Text))
            {
                var dialog = new FolderBrowserDialog();
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    txtExportDir.Text = dialog.SelectedPath;
                }
                else
                {
                    return;
                }
            }

            ExportChangeFiles();
        }

        #endregion

        #region method

        /// <summary>
        /// 加载提交信息
        /// </summary>
        /// <param name="commitName"></param>
        private async void LoadCommit(string commitName)
        {
            var commit = await Task.Run(() => _gitReader.GetCommit(commitName));
            // 加载备注信息
            txtCommitInfo.Text = string.Format("SHA-1: {0}\r\n{1}", commit.Hash, commit.Message);
            // 加载修改的文件
            var repoDir = _gitReader.Dir;
            lvwChangeList.Items.Clear();
            foreach (var change in commit.Changes)
            {
                lvwChangeList.Items.Add(new ListViewItem(new[]
                {
                    change.Path,
                    change.ChangeType.ToString(),
                    GetFileLastWriteTime(repoDir + change.Path)
                }));
            }
            lblChangeInfo.Text = string.Format("Added:{0}   Modified:{1}   Deleted:{2}   Renamed:{3}",
                commit.Changes.Count(m => m.ChangeType == ChangeType.Added),
                commit.Changes.Count(m => m.ChangeType == ChangeType.Modified),
                commit.Changes.Count(m => m.ChangeType == ChangeType.Deleted),
                commit.Changes.Count(m => m.ChangeType == ChangeType.Renamed)
                );
        }

        /// <summary>
        /// 导出修改的文件
        /// </summary>
        private async void ExportChangeFiles()
        {
            try
            {

                var commitName = lvwCommitList.SelectedItems[0].Tag.ToString();
                var changeFiles = await Task.Run(() => _gitReader.GetChangeFileList(commitName));
                foreach (var changeFile in changeFiles)
                {
                    CopyFile(_gitReader.Dir, txtExportDir.Text, changeFile.Replace("/", @"\"));
                }

                MessageBox.Show("导出完成", "完成", MessageBoxButtons.OK, MessageBoxIcon.Information);

                System.Diagnostics.Process.Start("Explorer.exe", txtExportDir.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show("导出失败:" + ex.Message, "失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        /// <summary>
        /// 复制文件
        /// </summary>
        /// <param name="fromDir">源路径</param>
        /// <param name="toDir">目标路径</param>
        /// <param name="file">文件</param>
        /// <returns></returns>
        private static void CopyFile(string fromDir, string toDir, string file)
        {
            var fromFile = (fromDir + @"\" + file);
            var toFile = (toDir + @"\" + file);

            if (File.Exists(fromFile))
            {
                Directory.CreateDirectory(toFile.Substring(0, toFile.LastIndexOf('\\')));
                File.Copy(fromFile, toFile, true);
            }
        }
        /// <summary>
        /// 获取文件最后修改时间
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <returns></returns>
        private static string GetFileLastWriteTime(string path)
        {
            return File.Exists(path) ? File.GetLastWriteTime(path).ToString("yyyy-MM-dd HH:mm:ss") : string.Empty;
        }

        #endregion
    }
}